if 'google.colab' in str(get_ipython()):
import os, sys
os.chdir('/content')
print('Nastavení prostředí Google Colab.')
! git clone "https://github.com/jarbes/snemovna.git" --branch master
sys.path.insert(0,'/content/snemovna')
os.chdir('/content/snemovna')
! pip install -r requirements.txt
Requirement already satisfied: bs4 in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 1)) (0.0.1) Requirement already satisfied: dash in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 2)) (1.19.0) Requirement already satisfied: html2text in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 3)) (2020.1.16) Requirement already satisfied: html5lib in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 4)) (1.1) Requirement already satisfied: jupyterlab in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 5)) (3.0.12) Requirement already satisfied: matplotlib in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 6)) (3.4.1) Requirement already satisfied: numpy>=1.18.4 in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 7)) (1.20.2) Requirement already satisfied: pandas==1.1.5 in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 8)) (1.1.5) Requirement already satisfied: plotly in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 9)) (4.14.3) Requirement already satisfied: requests in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 10)) (2.25.1) Requirement already satisfied: joblib in ./venv/lib/python3.8/site-packages (from -r requirements.txt (line 11)) (1.0.1) Requirement already satisfied: beautifulsoup4 in ./venv/lib/python3.8/site-packages (from bs4->-r requirements.txt (line 1)) (4.9.3) Requirement already satisfied: future in ./venv/lib/python3.8/site-packages (from dash->-r requirements.txt (line 2)) (0.18.2) Requirement already satisfied: dash-core-components==1.15.0 in ./venv/lib/python3.8/site-packages (from dash->-r requirements.txt (line 2)) (1.15.0) Requirement already satisfied: dash-html-components==1.1.2 in ./venv/lib/python3.8/site-packages (from dash->-r requirements.txt (line 2)) (1.1.2) Requirement already satisfied: dash-table==4.11.2 in ./venv/lib/python3.8/site-packages (from dash->-r requirements.txt (line 2)) (4.11.2) Requirement already satisfied: dash-renderer==1.9.0 in ./venv/lib/python3.8/site-packages (from dash->-r requirements.txt (line 2)) (1.9.0) Requirement already satisfied: flask-compress in ./venv/lib/python3.8/site-packages (from dash->-r requirements.txt (line 2)) (1.9.0) Requirement already satisfied: Flask>=1.0.4 in ./venv/lib/python3.8/site-packages (from dash->-r requirements.txt (line 2)) (1.1.2) Requirement already satisfied: webencodings in ./venv/lib/python3.8/site-packages (from html5lib->-r requirements.txt (line 4)) (0.5.1) Requirement already satisfied: six>=1.9 in ./venv/lib/python3.8/site-packages (from html5lib->-r requirements.txt (line 4)) (1.15.0) Requirement already satisfied: jupyter-packaging~=0.7.3 in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (0.7.12) Requirement already satisfied: packaging in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (20.9) Requirement already satisfied: ipython in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (7.22.0) Requirement already satisfied: tornado>=6.1.0 in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (6.1) Requirement already satisfied: nbclassic~=0.2 in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (0.2.6) Requirement already satisfied: jupyter-core in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (4.7.1) Requirement already satisfied: jupyterlab-server~=2.3 in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (2.4.0) Requirement already satisfied: jupyter-server~=1.4 in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (1.5.1) Requirement already satisfied: jinja2>=2.10 in ./venv/lib/python3.8/site-packages (from jupyterlab->-r requirements.txt (line 5)) (2.11.3) Requirement already satisfied: cycler>=0.10 in ./venv/lib/python3.8/site-packages (from matplotlib->-r requirements.txt (line 6)) (0.10.0) Requirement already satisfied: pyparsing>=2.2.1 in ./venv/lib/python3.8/site-packages (from matplotlib->-r requirements.txt (line 6)) (2.4.7) Requirement already satisfied: pillow>=6.2.0 in ./venv/lib/python3.8/site-packages (from matplotlib->-r requirements.txt (line 6)) (8.2.0) Requirement already satisfied: kiwisolver>=1.0.1 in ./venv/lib/python3.8/site-packages (from matplotlib->-r requirements.txt (line 6)) (1.3.1) Requirement already satisfied: python-dateutil>=2.7 in ./venv/lib/python3.8/site-packages (from matplotlib->-r requirements.txt (line 6)) (2.8.1) Requirement already satisfied: pytz>=2017.2 in ./venv/lib/python3.8/site-packages (from pandas==1.1.5->-r requirements.txt (line 8)) (2021.1) Requirement already satisfied: retrying>=1.3.3 in ./venv/lib/python3.8/site-packages (from plotly->-r requirements.txt (line 9)) (1.3.3) Requirement already satisfied: chardet<5,>=3.0.2 in ./venv/lib/python3.8/site-packages (from requests->-r requirements.txt (line 10)) (4.0.0) Requirement already satisfied: urllib3<1.27,>=1.21.1 in ./venv/lib/python3.8/site-packages (from requests->-r requirements.txt (line 10)) (1.26.4) Requirement already satisfied: idna<3,>=2.5 in ./venv/lib/python3.8/site-packages (from requests->-r requirements.txt (line 10)) (2.10) Requirement already satisfied: certifi>=2017.4.17 in ./venv/lib/python3.8/site-packages (from requests->-r requirements.txt (line 10)) (2020.12.5) Requirement already satisfied: soupsieve>1.2; python_version >= "3.0" in ./venv/lib/python3.8/site-packages (from beautifulsoup4->bs4->-r requirements.txt (line 1)) (2.2.1) Requirement already satisfied: brotli in ./venv/lib/python3.8/site-packages (from flask-compress->dash->-r requirements.txt (line 2)) (1.0.9) Requirement already satisfied: itsdangerous>=0.24 in ./venv/lib/python3.8/site-packages (from Flask>=1.0.4->dash->-r requirements.txt (line 2)) (1.1.0) Requirement already satisfied: Werkzeug>=0.15 in ./venv/lib/python3.8/site-packages (from Flask>=1.0.4->dash->-r requirements.txt (line 2)) (1.0.1) Requirement already satisfied: click>=5.1 in ./venv/lib/python3.8/site-packages (from Flask>=1.0.4->dash->-r requirements.txt (line 2)) (7.1.2) Requirement already satisfied: setuptools>=18.5 in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (44.0.0) Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (3.0.18) Requirement already satisfied: pexpect>4.3; sys_platform != "win32" in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (4.8.0) Requirement already satisfied: pickleshare in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (0.7.5) Requirement already satisfied: jedi>=0.16 in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (0.18.0) Requirement already satisfied: backcall in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (0.2.0) Requirement already satisfied: traitlets>=4.2 in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (5.0.5) Requirement already satisfied: pygments in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (2.8.1) Requirement already satisfied: decorator in ./venv/lib/python3.8/site-packages (from ipython->jupyterlab->-r requirements.txt (line 5)) (5.0.5) Requirement already satisfied: notebook<7 in ./venv/lib/python3.8/site-packages (from nbclassic~=0.2->jupyterlab->-r requirements.txt (line 5)) (6.3.0) Requirement already satisfied: json5 in ./venv/lib/python3.8/site-packages (from jupyterlab-server~=2.3->jupyterlab->-r requirements.txt (line 5)) (0.9.5) Requirement already satisfied: babel in ./venv/lib/python3.8/site-packages (from jupyterlab-server~=2.3->jupyterlab->-r requirements.txt (line 5)) (2.9.0) Requirement already satisfied: jsonschema>=3.0.1 in ./venv/lib/python3.8/site-packages (from jupyterlab-server~=2.3->jupyterlab->-r requirements.txt (line 5)) (3.2.0) Requirement already satisfied: nbformat in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (5.1.3) Requirement already satisfied: pyzmq>=17 in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (22.0.3) Requirement already satisfied: jupyter-client>=6.1.1 in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (6.1.12) Requirement already satisfied: nbconvert in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (6.0.7) Requirement already satisfied: argon2-cffi in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (20.1.0) Requirement already satisfied: Send2Trash in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (1.5.0) Requirement already satisfied: ipython-genutils in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.2.0) Requirement already satisfied: anyio>=2.0.2 in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (2.2.0) Requirement already satisfied: terminado>=0.8.3 in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.9.4) Requirement already satisfied: prometheus-client in ./venv/lib/python3.8/site-packages (from jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.10.0) Requirement already satisfied: MarkupSafe>=0.23 in ./venv/lib/python3.8/site-packages (from jinja2>=2.10->jupyterlab->-r requirements.txt (line 5)) (1.1.1) Requirement already satisfied: wcwidth in ./venv/lib/python3.8/site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython->jupyterlab->-r requirements.txt (line 5)) (0.2.5) Requirement already satisfied: ptyprocess>=0.5 in ./venv/lib/python3.8/site-packages (from pexpect>4.3; sys_platform != "win32"->ipython->jupyterlab->-r requirements.txt (line 5)) (0.7.0) Requirement already satisfied: parso<0.9.0,>=0.8.0 in ./venv/lib/python3.8/site-packages (from jedi>=0.16->ipython->jupyterlab->-r requirements.txt (line 5)) (0.8.2) Requirement already satisfied: ipykernel in ./venv/lib/python3.8/site-packages (from notebook<7->nbclassic~=0.2->jupyterlab->-r requirements.txt (line 5)) (5.5.3) Requirement already satisfied: pyrsistent>=0.14.0 in ./venv/lib/python3.8/site-packages (from jsonschema>=3.0.1->jupyterlab-server~=2.3->jupyterlab->-r requirements.txt (line 5)) (0.17.3) Requirement already satisfied: attrs>=17.4.0 in ./venv/lib/python3.8/site-packages (from jsonschema>=3.0.1->jupyterlab-server~=2.3->jupyterlab->-r requirements.txt (line 5)) (20.3.0) Requirement already satisfied: pandocfilters>=1.4.1 in ./venv/lib/python3.8/site-packages (from nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (1.4.3) Requirement already satisfied: entrypoints>=0.2.2 in ./venv/lib/python3.8/site-packages (from nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.3) Requirement already satisfied: mistune<2,>=0.8.1 in ./venv/lib/python3.8/site-packages (from nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.8.4) Requirement already satisfied: jupyterlab-pygments in ./venv/lib/python3.8/site-packages (from nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.1.2) Requirement already satisfied: bleach in ./venv/lib/python3.8/site-packages (from nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (3.3.0) Requirement already satisfied: defusedxml in ./venv/lib/python3.8/site-packages (from nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.7.1) Requirement already satisfied: nbclient<0.6.0,>=0.5.0 in ./venv/lib/python3.8/site-packages (from nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.5.3) Requirement already satisfied: testpath in ./venv/lib/python3.8/site-packages (from nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (0.4.4) Requirement already satisfied: cffi>=1.0.0 in ./venv/lib/python3.8/site-packages (from argon2-cffi->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (1.14.5) Requirement already satisfied: sniffio>=1.1 in ./venv/lib/python3.8/site-packages (from anyio>=2.0.2->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (1.2.0) Requirement already satisfied: async-generator in ./venv/lib/python3.8/site-packages (from nbclient<0.6.0,>=0.5.0->nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (1.10) Requirement already satisfied: nest-asyncio in ./venv/lib/python3.8/site-packages (from nbclient<0.6.0,>=0.5.0->nbconvert->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (1.5.1) Requirement already satisfied: pycparser in ./venv/lib/python3.8/site-packages (from cffi>=1.0.0->argon2-cffi->jupyter-server~=1.4->jupyterlab->-r requirements.txt (line 5)) (2.20)
from datetime import datetime, timedelta
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
import numpy as np
from snemovna.Hlasovani import Hlasovani, Omluvy, HlasovaniPoslanci, ZpochybneniHlasovani, ZmatecneHlasovani
from snemovna.PoslanciOsoby import Poslanci, Organy, ZarazeniOsoby
from snemovna.Stenotexty import Stenotexty
from snemovna.Schuze import Schuze
from snemovna.utility import groupby_bar, sort_column_by_predefined_order
from nastav_jupyter_notebook import nastav_pandas
# nastavení výpisu, například zobrazení delších textů v sloupcích tabulek
nastav_pandas()
clean_layout = dict(
plot_bgcolor="#FFFFFF",
)
y_spikes = dict(
yaxis=dict(
linecolor="#BCCCDC",
showspikes=True,
spikethickness=1,
spikedash="dot",
spikecolor="#999999",
spikemode="across",
)
)
x_spikes = dict(
xaxis=dict(
linecolor="#BCCCDC",
showspikes=True,
spikethickness=1,
spikedash="dot",
spikecolor="#999999",
spikemode="across",
)
)
clean_layout_with_x_spikes = {**clean_layout, **x_spikes}
clean_layout_with_y_spikes = {**clean_layout, **y_spikes}
clean_layout_with_xy_spikes = {**clean_layout, **x_spikes, **y_spikes}
categorical_scale1 = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']
# formát výpisu data
format_den = "%d. %m. %Y"
stahni=True
# načti informace o poslancích (jméno, příjemní, za koho kandidovali, etc.)
p = Poslanci(stahni=stahni)
print(p.columns)
p.head(2)
2021-04-07:03:23:49 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/poslanci.zip'. 2021-04-07:03:23:51 WARNING [Snemovna.py:149] While merging 'funkce' with 'typ_funkce': Dropping ['id_typ_organ__typ_funkce', 'typ_organ_obecny__typ_funkce', 'typ_id_typ_organ__typ_funkce', 'nazev_typ_organ_en__typ_funkce', 'nazev_typ_organ_cz__typ_funkce'] because of abundance.
Index(['id_poslanec', 'id_osoba', 'id_kraj', 'id_kandidatka', 'id_organ',
'web', 'ulice', 'obec', 'psc', 'email', 'telefon', 'fax', 'psp_telefon',
'facebook', 'foto', 'pred', 'prijmeni', 'jmeno', 'za', 'narozeni',
'zmena', 'umrti', 'pohlavi', 'adresa', 'sirka', 'delka',
'nazev_kandidatka_cz', 'zkratka_kandidatka', 'nazev_kraj_cz',
'zkratka_kraj', 'id_parlament', 'od_parlament', 'do_parlament',
'id_klub', 'nazev_klub_cz', 'zkratka_klub', 'od_klub', 'do_klub'],
dtype='object')
| id_poslanec | id_osoba | id_kraj | id_kandidatka | id_organ | web | ulice | obec | psc | ... | nazev_kraj_cz | zkratka_kraj | id_parlament | od_parlament | do_parlament | id_klub | nazev_klub_cz | zkratka_klub | od_klub | do_klub | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| index | |||||||||||||||||||||
| 0 | 1521 | 5700 | 588 | 155 | 172 | <NA> | Vančurovo nám. 663 | Hradec Králové | 50002 | adameci@psp.cz | ... | Královéhradecký | HK | 172 | 2017-10-21 14:00:00+02:00 | NaT | 1295 | Poslanecký klub Občanské demokratické strany | ODS | 2017-10-24 00:00:00+02:00 | NaT |
| 1 | 1522 | 6254 | 581 | 1104 | 172 | <NA> | Dobronická 1257 | Praha 4 - Kunratice | 14800 | adamkovav@psp.cz | ... | Hlavní město Praha | PH | 172 | 2017-10-21 14:00:00+02:00 | NaT | 1292 | Poslanecký klub ANO 2011 | ANO | 2017-10-24 00:00:00+02:00 | NaT |
2 rows × 38 columns
zo = ZarazeniOsoby(stahni=stahni)
print(zo.columns)
zo.head(2)
2021-04-07:03:23:52 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/poslanci.zip'. 2021-04-07:03:23:54 WARNING [Snemovna.py:149] While merging 'funkce' with 'typ_funkce': Dropping ['id_typ_organ__typ_funkce', 'typ_organ_obecny__typ_funkce', 'typ_id_typ_organ__typ_funkce', 'nazev_typ_organ_en__typ_funkce', 'nazev_typ_organ_cz__typ_funkce'] because of abundance.
Index(['id_osoba', 'id_of', 'cl_funkce__ORIG', 'od_o', 'do_o', 'od_f', 'do_f',
'cl_funkce', 'pred', 'prijmeni', 'jmeno', 'za', 'narozeni',
'pohlavi__ORIG', 'zmena', 'umrti', 'pohlavi', 'id_organ',
'organ_id_organ', 'id_typ_organ', 'zkratka', 'nazev_organ_cz',
'nazev_organ_en', 'od_organ', 'do_organ', 'cl_organ_base',
'typ_id_typ_organ', 'nazev_typ_organ_cz', 'nazev_typ_organ_en',
'typ_organ_obecny', 'id_funkce', 'id_typ_funkce', 'nazev_funkce_cz',
'priorita', 'typ_funkce_cz', 'typ_funkce_en', 'typ_funkce_obecny__ORIG',
'typ_funkce_obecny'],
dtype='object')
| id_osoba | id_of | cl_funkce__ORIG | od_o | do_o | od_f | do_f | cl_funkce | pred | prijmeni | ... | nazev_typ_organ_en | typ_organ_obecny | id_funkce | id_typ_funkce | nazev_funkce_cz | priorita | typ_funkce_cz | typ_funkce_en | typ_funkce_obecny__ORIG | typ_funkce_obecny | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| index | |||||||||||||||||||||
| 38 | 4 | 172 | 0 | 2017-10-21 14:00:00+02:00 | NaT | NaT | NaT | členství | Benda | ... | Parliament | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | |
| 95 | 4 | 1295 | 0 | 2017-10-24 00:00:00+02:00 | NaT | NaT | NaT | členství | Benda | ... | Political Group | 1 | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> | <NA> |
2 rows × 38 columns
# načti informace o schůzích PS (kdy začaly, v jakém jsou stavu, etc.)
sch = Schuze(stahni=stahni)
print(sch.columns)
sch.head(2)
2021-04-07:03:23:54 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/poslanci.zip'. 2021-04-07:03:23:56 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/schuze.zip'.
Index(['id_schuze', 'id_org', 'schuze', 'od_schuze', 'do_schuze',
'aktualizace', 'pozvanka', 'text_dt', 'text_st', 'tm_line', 'stav',
'typ'],
dtype='object')
| id_schuze | id_org | schuze | od_schuze | do_schuze | aktualizace | pozvanka | text_dt | text_st | tm_line | stav | typ | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 469 | 172 | 1 | 2017-11-20 13:00:00+01:00 | NaT | 2017-11-08 08:58 | navržený pořad | <NA> | <NA> | <NA> | OK | řádná |
| 1 | 469 | 172 | 1 | 2017-11-20 13:00:00+01:00 | 2017-11-24 14:09:00+01:00 | 2017-11-24 14:09 | <NA> | <NA> | <NA> | <NA> | OK | řádná |
# načti informace o jednotlivých hlasováních
h = Hlasovani(stahni=stahni)
print(h.columns)
h.head(2)
2021-04-07:03:23:58 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/poslanci.zip'. 2021-04-07:03:23:59 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/hl-2017ps.zip'.
Index(['id_hlasovani', 'id_organ', 'schuze', 'cislo', 'bod', 'cas', 'pro',
'proti', 'zdrzel', 'nehlasoval', 'prihlaseno', 'kvorum', 'nazev_dlouhy',
'nazev_kratky', 'datum', 'bod__KAT', 'vysledek', 'druh_hlasovani',
'ma_zpochybneni', 'je_zmatecne', 'ma_stenozaznam', 'turn', 'typ'],
dtype='object')
| id_hlasovani | id_organ | schuze | cislo | bod | cas | pro | proti | zdrzel | nehlasoval | ... | nazev_kratky | datum | bod__KAT | vysledek | druh_hlasovani | ma_zpochybneni | je_zmatecne | ma_stenozaznam | turn | typ | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 67018 | 172 | 1 | 1 | 3 | 13:53:00 | 191 | 0 | 5 | 0 | ... | <NA> | 2017-11-20 13:53:00+01:00 | normální | přijato | normální | False | True | False | <NA> | <NA> |
| 1 | 67019 | 172 | 1 | 2 | 3 | 13:53:00 | 194 | 0 | 4 | 0 | ... | <NA> | 2017-11-20 13:53:00+01:00 | normální | přijato | normální | False | False | False | <NA> | <NA> |
2 rows × 23 columns
zph = ZpochybneniHlasovani(stahni=stahni)
print(zph.columns)
zph.head()
2021-04-07:03:24:02 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/poslanci.zip'. 2021-04-07:03:24:04 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/hl-2017ps.zip'. 2021-04-07:03:24:06 WARNING [Snemovna.py:149] While merging 'zpochybneni' with 'hlasovani': Dropping ['turn__hlasovani'] because of abundance. 2021-04-07:03:24:06 WARNING [Snemovna.py:184] Pro sloupec 'je_platne' nebyla nalezena metadata!
Index(['id_hlasovani', 'turn', 'mode', 'id_h2', 'id_h3', 'mode__KAT',
'je_platne', 'id_organ', 'schuze', 'cislo', 'bod', 'datum__ORIG', 'cas',
'pro', 'proti', 'zdrzel', 'nehlasoval', 'prihlaseno', 'kvorum',
'druh_hlasovani__ORIG', 'vysledek__ORIG', 'nazev_dlouhy',
'nazev_kratky', 'datum', 'bod__KAT', 'vysledek', 'druh_hlasovani',
'ma_zpochybneni', 'je_zmatecne', 'ma_stenozaznam', 'typ__ORIG', 'typ'],
dtype='object')
| id_hlasovani | turn | mode | id_h2 | id_h3 | mode__KAT | je_platne | id_organ | schuze | cislo | ... | nazev_kratky | datum | bod__KAT | vysledek | druh_hlasovani | ma_zpochybneni | je_zmatecne | ma_stenozaznam | typ__ORIG | typ | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 55680 | 67 | 0 | 55681 | 55682 | žádost o opakování | True | <NA> | <NA> | <NA> | ... | <NA> | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> |
| 1 | 55664 | 43 | 0 | 55665 | 55666 | žádost o opakování | True | <NA> | <NA> | <NA> | ... | <NA> | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> |
| 2 | 55590 | 244 | 0 | 55591 | 55592 | žádost o opakování | True | <NA> | <NA> | <NA> | ... | <NA> | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> |
| 3 | 55561 | 200 | 0 | 55562 | 55563 | žádost o opakování | True | <NA> | <NA> | <NA> | ... | <NA> | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> |
| 4 | 55555 | 199 | 0 | 55556 | 55557 | žádost o opakování | True | <NA> | <NA> | <NA> | ... | <NA> | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> |
5 rows × 32 columns
zmh = ZmatecneHlasovani(stahni=stahni)
print(zmh.columns)
zmh.head()
2021-04-07:03:24:06 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/poslanci.zip'. 2021-04-07:03:24:08 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/hl-2017ps.zip'.
Index(['id_hlasovani', 'id_organ', 'schuze', 'cislo', 'bod', 'datum__ORIG',
'cas', 'pro', 'proti', 'zdrzel', 'nehlasoval', 'prihlaseno', 'kvorum',
'druh_hlasovani__ORIG', 'vysledek__ORIG', 'nazev_dlouhy',
'nazev_kratky', 'datum', 'bod__KAT', 'vysledek', 'druh_hlasovani',
'ma_zpochybneni', 'je_zmatecne', 'ma_stenozaznam', 'turn', 'typ__ORIG',
'typ'],
dtype='object')
| id_hlasovani | id_organ | schuze | cislo | bod | datum__ORIG | cas | pro | proti | zdrzel | ... | datum | bod__KAT | vysledek | druh_hlasovani | ma_zpochybneni | je_zmatecne | ma_stenozaznam | turn | typ__ORIG | typ | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 6018 | <NA> | <NA> | <NA> | <NA> | <NA> | NaN | <NA> | <NA> | <NA> | ... | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> | <NA> |
| 1 | 7496 | <NA> | <NA> | <NA> | <NA> | <NA> | NaN | <NA> | <NA> | <NA> | ... | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> | <NA> |
| 2 | 7506 | <NA> | <NA> | <NA> | <NA> | <NA> | NaN | <NA> | <NA> | <NA> | ... | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> | <NA> |
| 3 | 7854 | <NA> | <NA> | <NA> | <NA> | <NA> | NaN | <NA> | <NA> | <NA> | ... | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> | <NA> |
| 4 | 7934 | <NA> | <NA> | <NA> | <NA> | <NA> | NaN | <NA> | <NA> | <NA> | ... | NaT | <NA> | <NA> | <NA> | NaN | NaN | NaN | <NA> | <NA> | <NA> |
5 rows × 27 columns
# načti indiviuální hlasování poslanců
hp = HlasovaniPoslanci(stahni=stahni)
print(hp.columns)
hp.head(2)
2021-04-07:03:24:12 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/poslanci.zip'. 2021-04-07:03:24:13 WARNING [Snemovna.py:149] While merging 'funkce' with 'typ_funkce': Dropping ['id_typ_organ__typ_funkce', 'typ_organ_obecny__typ_funkce', 'typ_id_typ_organ__typ_funkce', 'nazev_typ_organ_en__typ_funkce', 'nazev_typ_organ_cz__typ_funkce'] because of abundance. 2021-04-07:03:24:14 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/hl-2017ps.zip'.
Index(['id_hlasovani', 'nazev_dlouhy', 'vysledek', 'id_poslanec', 'id_osoba',
'pred', 'jmeno', 'prijmeni', 'id_klub', 'nazev_klub_cz', 'zkratka_klub',
'narozeni', 'pohlavi', 'za', 'id_kraj', 'nazev_kraj_cz', 'zkratka_kraj',
'id_kandidatka', 'nazev_kandidatka_cz', 'zkratka_kandidatka', 'schuze',
'cislo', 'bod', 'cas', 'datum', 'bod__KAT', 'druh_hlasovani',
'ma_zpochybneni', 'id_parlament', 'id_organ', 'od_klub', 'do_klub',
'je_zmatecne'],
dtype='object')
| id_hlasovani | nazev_dlouhy | vysledek | id_poslanec | id_osoba | pred | jmeno | prijmeni | id_klub | nazev_klub_cz | ... | cas | datum | bod__KAT | druh_hlasovani | ma_zpochybneni | id_parlament | id_organ | od_klub | do_klub | je_zmatecne | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| index | |||||||||||||||||||||
| 0 | 67018 | Inf. o ustavení volební komise PS a volbě členů | ano | 1521 | 5700 | Mgr. | Ivan | Adamec | 1295 | Poslanecký klub Občanské demokratické strany | ... | 13:53:00 | 2017-11-20 13:53:00+01:00 | normální | normální | False | 172 | 172 | 2017-10-24 00:00:00+02:00 | NaT | True |
| 1 | 67018 | Inf. o ustavení volební komise PS a volbě členů | ano | 1522 | 6254 | prof. MUDr. | Věra | Adámková | 1292 | Poslanecký klub ANO 2011 | ... | 13:53:00 | 2017-11-20 13:53:00+01:00 | normální | normální | False | 172 | 172 | 2017-10-24 00:00:00+02:00 | NaT | True |
2 rows × 33 columns
assert hp.id_osoba.nunique() <= p.id_osoba.nunique() or print("Nekonzistence v tabulkách 'HlasovaniPoslanci' a 'Poslanci': hlasujících poslanců je méně než těch, kteří hlasovali!")
# načti omluvy poslanců ze schůze PS
om = Omluvy(stahni=stahni)
print(om.columns)
om.head(2)
2021-04-07:03:24:38 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/poslanci.zip'. 2021-04-07:03:24:40 WARNING [Snemovna.py:149] While merging 'funkce' with 'typ_funkce': Dropping ['id_typ_organ__typ_funkce', 'typ_organ_obecny__typ_funkce', 'typ_id_typ_organ__typ_funkce', 'nazev_typ_organ_en__typ_funkce', 'nazev_typ_organ_cz__typ_funkce'] because of abundance. 2021-04-07:03:24:41 INFO [utility.py:21] Stahuji 'https://www.psp.cz/eknih/cdrom/opendata/hl-2017ps.zip'. 2021-04-07:03:24:44 WARNING [Snemovna.py:149] While merging 'omluvy' with 'poslanci': Dropping ['id_organ__poslanci'] because of abundance.
Index(['id_organ', 'id_poslanec', 'den__ORIG', 'od__ORIG', 'do__ORIG', 'od',
'do', 'den', 'id_osoba', 'id_kraj', 'id_kandidatka', 'web', 'ulice',
'obec', 'psc', 'email', 'telefon', 'fax', 'psp_telefon', 'facebook',
'foto', 'pred', 'prijmeni', 'jmeno', 'za', 'narozeni', 'pohlavi__ORIG',
'zmena', 'umrti', 'pohlavi', 'adresa', 'sirka', 'delka',
'nazev_kandidatka_cz', 'zkratka_kandidatka', 'nazev_kraj_cz',
'zkratka_kraj', 'id_parlament', 'od_parlament', 'do_parlament',
'id_klub', 'nazev_klub_cz', 'zkratka_klub', 'od_klub', 'do_klub',
'je_poslanec'],
dtype='object')
| id_organ | id_poslanec | den__ORIG | od__ORIG | do__ORIG | od | do | den | id_osoba | id_kraj | ... | zkratka_kraj | id_parlament | od_parlament | do_parlament | id_klub | nazev_klub_cz | zkratka_klub | od_klub | do_klub | je_poslanec | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| index | |||||||||||||||||||||
| 21451 | 172 | 1554 | 20.11.2017 | <NA> | <NA> | NaN | NaN | 2017-11-20 00:00:00+01:00 | 5261 | 581 | ... | PH | 172 | 2017-10-21 14:00:00+02:00 | NaT | 1293 | Poslanecký klub Komunistické strany Čech a Moravy | KSČM | 2017-10-24 00:00:00+02:00 | NaT | True |
| 21452 | 172 | 1533 | 22.11.2017 | <NA> | <NA> | NaN | NaN | 2017-11-22 00:00:00+01:00 | 6002 | 590 | ... | V | 172 | 2017-10-21 14:00:00+02:00 | NaT | 1294 | Poslanecký klub České strany sociálně demokratické | ČSSD | 2017-10-27 00:00:00+02:00 | NaT | True |
2 rows × 46 columns
assert om[om.je_poslanec].id_osoba.nunique() <= p.id_osoba.nunique() or print("Nekonzistence v tabulkách 'Omluvy' a 'Poslanci': osob je méně než osob, které se omlouvali!")
# Stenotexty zde nebudeme potřebovat
#st = Stenotexty(stahni=stahni)
#print(st.columns)
#st.head()
volebni_obdobi = h.volebni_obdobi
snemovna = h.snemovna
pocet_poslancu_dle_klubu = p[p.do_parlament.isna()].groupby('zkratka_klub').size().sort_values(ascending=False)
fig = go.Figure(go.Bar(
x=pocet_poslancu_dle_klubu.index,
y=pocet_poslancu_dle_klubu.values,
marker=dict(
color=list(range(len(pocet_poslancu_dle_klubu.index))),
colorscale=categorical_scale1
),
hovertemplate="<b>%{x}</b><br>Počet poslanců: %{y}<extra></extra>"
))
layout = go.Layout(
title="Aktuální počet poslanců dle poslaneckého klubu (strany)",
xaxis=dict(title="Strana", type='category'),
yaxis=dict(title="Počet poslanců")
)
fig.update_layout(clean_layout_with_y_spikes)
fig.update_layout(layout)
fig.show()
fig = go.Figure()
schuze = sch[sch.pozvanka.isna()]
for _, s in schuze.iterrows():
id_schuze = s.schuze
dny_hlasovani = h[h.schuze == id_schuze].datum.dt.date.unique()
od = s.od_schuze
do = sch.tzn.localize(datetime.today()) if pd.isna(s.do_schuze) else s.do_schuze
dny = [od.date()] + [d for d in dny_hlasovani if (d >= od.date()) and ((d <= do.date()) | pd.isna(do))] + [do.date()]
dny = list(set(dny))
datum_hovertemplate = f"od {od.strftime(format_den)}" if pd.isna(s.do_schuze) \
else f"{od.strftime(format_den)} - {s.do_schuze.strftime(format_den)}"
tm_line_hovertemplate= '' if pd.isna(s.tm_line) else s.tm_line
fig.add_trace(go.Scatter(
x=dny,
y=[s.schuze]*len(dny),
text=s.schuze,
hovertemplate=f"Schůze {s.schuze}<br>" \
"Datum: %{x}<br>"\
f"Trvání schůze: {datum_hovertemplate}<br>"\
f"Typ schůze: {s.typ}<br>" \
f"{tm_line_hovertemplate}<extra></extra>",
mode="lines+markers",
line = dict(shape='linear', width=15),
marker = dict(symbol='star-diamond', size=10),
))
fig.update_traces(marker=dict(line=dict(width=1, color='black')))
fig.update_layout(clean_layout_with_xy_spikes)
layout = go.Layout(
title="Schůze poslanecké sněmovny v čase",
xaxis=dict(title="Čas"),
yaxis=dict(title="Schůze", type='category'),
height=600,
showlegend=False
)
fig.update_layout(layout)
fig.show()
import plotly.express as px
h["pocet_dni_na_schuzi"] = h.groupby(["schuze"]).datum.transform('nunique')
h['den'] = h.datum.dt.date
h["den_schuze"] = h.groupby(["schuze", h.datum.dt.date]).ngroup()
h["den_schuze_min"] = h.groupby(["schuze"]).den_schuze.transform(min)
h["den_schuze_rank"] = (h["den_schuze"] - h["den_schuze_min"] + 1)
x1 = h.groupby(["schuze", 'den', "den_schuze_rank"]).size()
z1 = x1.reset_index(name="pocet_hlasovani")
print(f"Na schůzích {sorted(set(range(z1.schuze.max() + 1)) - set(z1.schuze.unique()) - set([0]))} se nehlasovalo.")
fig = px.bar(z1, x="schuze", y="pocet_hlasovani",
color="den_schuze_rank",
hover_data=['schuze', 'den_schuze_rank', 'pocet_hlasovani', 'den'],
labels={'schuze':'Schůze', 'den': 'Datum', 'den_schuze_rank': 'Pořadí dne schůze', 'pocet_hlasovani': 'Počet hlasování'},
title="Počet hlasování dle dne schůze")
layout = go.Layout(
title="Počet hlasování dle schůze",
plot_bgcolor="#FFFFFF",
#hovermode="x",
#hoverdistance=100, # Distance to show hover label of data point
#spikedistance=1000, # Distance to show spike
xaxis=dict(
title="Schůze sněmovny",
linecolor="#BCCCDC",
#type='category'
),
yaxis=dict(
title="Počet hlasování",
linecolor="#BCCCDC",
showspikes=True,
spikethickness=1,
spikedash="dot",
spikecolor="#999999",
spikemode="across",
)
)
fig.update_layout(layout)
Na schůzích [10, 21, 71] se nehlasovalo.
def pocet_hlasovani_dle_data(df, resample_to, resample_str, resample_label):
frame = df.set_index('datum').resample(resample_to).size()
frame = frame.mask(frame == 0, None).dropna()
max_idx = frame.sort_values().index[-1]
min_idx = frame.sort_values().index[0]
print(f"Nejvíce hlasování ({frame.loc[max_idx]}) se uskutečnilo {max_idx.strftime(resample_str)}.")
print(f"Nejméně hlasování ({frame.loc[min_idx]}) se uskutečnilo {min_idx.strftime(resample_str)}.")
fig = go.Figure()
fig.add_trace(go.Bar(
x=frame.index,
y=frame.values,
marker=dict(
color=frame.values,
colorscale='Bluered'
),
hovertemplate="%{x}<br>počet hlasování: %{y}<extra></extra>"
))
fig.update_layout(
title=f"Počet hlasování dle data ({resample_label})",
xaxis_title=f"datum ({resample_label})",
yaxis_title="počet hlasování",
width=1200,
height=500
)
dt_all = pd.date_range(start=frame.index[0],end=frame.index[-1])
dt_obs = [d.strftime(resample_str) for d in frame.index]
dt_breaks = [d for d in dt_all.strftime(resample_str).tolist() if not d in dt_obs]
# nezobrazuj data bez hlasování
#dt_all = pd.date_range(start=df.index[0], end=df.index[-1])
#dt_obs = [d.strftime(resample_str) for d in df.index]
#dt_breaks = [d for d in dt_all.strftime(resample_str).tolist() if not d in dt_obs]
fig.update_xaxes(
rangebreaks=[dict(values=dt_breaks)]
)
fig.show()
pocet_hlasovani_dle_data(h, "D", "%Y-%m-%d", "den")
Nejvíce hlasování (387) se uskutečnilo 2019-06-05. Nejméně hlasování (1) se uskutečnilo 2018-07-12.
# Za hlasovací dny označujeme takové, během nichž se sešla Sněmovna a o něčem se hlasovalo.
# TODO: Existují dny, kdy se konala schůze PS, ale o ničem se nehlasovalo? Jak je najdeme?
minimalni_pocet_hlasovacich_dni = 30
hlasovaci_dny = pd.to_datetime(h.datum.dt.date.unique()).tz_localize(h.tzn)
pocet_hlasovacich_dni = len(hlasovaci_dny)
def fce_pocet_omluvenych_dni(id_poslanec):
return om[(om.je_poslanec) & (om.id_poslanec == id_poslanec)].den.dt.date.nunique()
p['pocet_omluvenych_dni'] = p.id_poslanec.apply(fce_pocet_omluvenych_dni).astype('Int64')
assert p[p['pocet_omluvenych_dni'] > pocet_hlasovacich_dni].index.size == 0, \
f"Chyba ve výpočtu. Počet omluvenych dní poslance musí být menší než {pocet_hlasovacich_dni}."
p['pocet_hlasovacich_dni'] = p.apply(lambda row:
len(hlasovaci_dny[(hlasovaci_dny >= row['od_parlament'])
& ((hlasovaci_dny <= row['do_parlament']) | pd.isna(row['do_parlament']))])
, axis=1).astype('Int64')
assert p[p['pocet_hlasovacich_dni'] > pocet_hlasovacich_dni].index.size == 0,\
f"Chyba ve výpočtu. Počet hlasovacích dní poslance musí být menší než {pocet_hlasovacich_dni}."
p['pomer_omluvenych_dni'] = p['pocet_omluvenych_dni'] / p['pocet_hlasovacich_dni']
assert p[
(p.pocet_hlasovacich_dni > minimalni_pocet_hlasovacich_dni)
& ((p['pomer_omluvenych_dni'] > 1) | (p['pomer_omluvenych_dni'] < 0))].index.size == 0,\
f"Chyba ve výpočtu. Poměr omluvených dní poslance musí být v intervalu [0, 1]]."
if pd.isna(h.snemovna.do_organ):
print(f"Sněmovna {volebni_obdobi} se začala scházet {snemovna.od_organ.strftime(format_den)}.")
if len(h) > 0:
print(f"Naposledy se hlasovalo {h.datum.sort_values().dt.strftime(format_den).iloc[-1]}.")
else:
print(f"Sněmovna {volebni_obdobi} se začala scházet {snemovna.od_organ.strftime(format_den)} a skončila {snemovna.do_organ.strftime(format_den)}.")
print(f"Hlasovalo se během {pocet_hlasovacich_dni} dní.")
Sněmovna 2017 se začala scházet 21. 10. 2017. Naposledy se hlasovalo 01. 04. 2021. Hlasovalo se během 276 dní.
print(f"Průměrný poměr omluvených dnů: {p[p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni].pomer_omluvenych_dni.mean():.2f}.")
print(f"Medián poměr omluvených dnů: {p[p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni].pomer_omluvenych_dni.median():.2f}.")
fig = go.Figure(go.Box(y=p[p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni].pomer_omluvenych_dni))
fig.show()
Průměrný poměr omluvených dnů: 0.41. Medián poměr omluvených dnů: 0.38.
fig = go.Figure()
for zkratka_klub in p.zkratka_klub.unique():
data = p[(p.zkratka_klub == zkratka_klub) & (p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)]
fig.add_trace(go.Box(y=data.pomer_omluvenych_dni, name=zkratka_klub))
layout = go.Layout(
title="Poměr počtu omluvených dní ku počtu hlasovacích dní dle poslaneckého klubu (strany)",
xaxis=dict(title="Strany", type='category'),
yaxis=dict(title="Poměr omluvených dní")
)
fig.update_layout(clean_layout_with_x_spikes)
fig.update_layout(layout)
fig.show()
data = pd.DataFrame([])
for zkratka_klub in p.zkratka_klub.unique():
v = p[(p.zkratka_klub == zkratka_klub) & (p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].pocet_omluvenych_dni.sum()
data.loc[zkratka_klub, 'pocet_omluvenych_dni'] = v
fig = go.Figure()
fig.add_trace(go.Bar(x=data.index, y=data.pocet_omluvenych_dni))
layout = go.Layout(
title="Počet omluvených dní dle poslaneckého klubu (strany)",
xaxis=dict(title="Strany", type='category'),
yaxis=dict(title="Poměr omluvených dní")
)
fig.update_layout(clean_layout_with_x_spikes)
fig.update_layout(layout)
fig.show()
print(f"Průměrný počet omluvených dnů: {p[(p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].pocet_omluvenych_dni.mean():.1f}.")
print(f"Medián počtu omluvených dnů: {p[(p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].pocet_omluvenych_dni.median():.1f}.")
Průměrný počet omluvených dnů: 105.3. Medián počtu omluvených dnů: 101.5.
go.Figure(go.Histogram(x=p[(p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].pomer_omluvenych_dni))
go.Figure(go.Histogram(x=p[(p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].pocet_omluvenych_dni))
cnt = 10
print(f"Poslanci s nejmenším počtem dnů, během nichž se omluvali z hlasování PS.")
fields = ['id_poslanec', 'jmeno', 'prijmeni', 'pomer_omluvenych_dni', 'pocet_omluvenych_dni', 'pocet_hlasovacich_dni', 'zkratka_klub']
p[(p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].sort_values(by="pocet_omluvenych_dni")[fields].head(cnt)
Poslanci s nejmenším počtem dnů, během nichž se omluvali z hlasování PS.
| id_poslanec | jmeno | prijmeni | pomer_omluvenych_dni | pocet_omluvenych_dni | pocet_hlasovacich_dni | zkratka_klub | |
|---|---|---|---|---|---|---|---|
| index | |||||||
| 86 | 1608 | Vladimír | Koníček | 0.051282 | 4 | 78 | KSČM |
| 132 | 1654 | Robert | Pelikán | 0.297872 | 14 | 47 | ANO |
| 191 | 1713 | Veronika | Vrecionová | 0.116279 | 15 | 129 | ODS |
| 131 | 1653 | Mikuláš | Peksa | 0.172131 | 21 | 122 | Piráti |
| 164 | 1686 | Martin | Stropnický | 0.714286 | 45 | 63 | ANO |
| 213 | 1735 | Jaroslav | Vymazal | 0.907407 | 49 | 54 | ODS |
| 190 | 1712 | Petr | Vrána | 0.259434 | 55 | 212 | ANO |
| 212 | 1734 | Irena | Blažková | 0.890625 | 57 | 64 | ANO |
| 64 | 1586 | Milan | Chovanec | 0.556604 | 59 | 106 | ČSSD |
| 157 | 1679 | Jan | Schiller | 0.254032 | 63 | 248 | ANO |
cnt = 10
print(f"Poslanci s největším počtem dnů, během nichž se omluvali z hlasování PS.")
fields = ['id_poslanec', 'jmeno', 'prijmeni', 'pomer_omluvenych_dni', 'pocet_omluvenych_dni', 'pocet_hlasovacich_dni', 'zkratka_klub']
p[(p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].sort_values(by="pocet_omluvenych_dni")[::-1][fields].head(cnt)
Poslanci s největším počtem dnů, během nichž se omluvali z hlasování PS.
| id_poslanec | jmeno | prijmeni | pomer_omluvenych_dni | pocet_omluvenych_dni | pocet_hlasovacich_dni | zkratka_klub | |
|---|---|---|---|---|---|---|---|
| index | |||||||
| 3 | 1524 | Andrej | Babiš | 0.807971 | 223 | 276 | ANO |
| 161 | 1683 | Antonín | Staněk | 0.735507 | 203 | 276 | ČSSD |
| 12 | 1533 | Jiří | Běhounek | 0.721014 | 199 | 276 | ČSSD |
| 158 | 1680 | Karel | Schwarzenberg | 0.721014 | 199 | 276 | TOP09 |
| 101 | 1623 | Jana | Levová | 0.710145 | 196 | 276 | SPD |
| 81 | 1603 | Jiří | Kobza | 0.626812 | 173 | 276 | SPD |
| 19 | 1541 | Jan | Birke | 0.615942 | 170 | 276 | ČSSD |
| 170 | 1692 | Julius | Špičák | 0.612319 | 169 | 276 | ANO |
| 56 | 1578 | Jan | Hamáček | 0.612319 | 169 | 276 | ČSSD |
| 63 | 1585 | Tereza | Hyťhová | 0.590580 | 163 | 276 | Nezařaz |
cnt = 10
print(f"Poslanci s nejmenším poměrem dnů, během nichž se omluvali z hlasování PS.")
fields = ['id_poslanec', 'jmeno', 'prijmeni', 'pomer_omluvenych_dni', 'pocet_omluvenych_dni', 'pocet_hlasovacich_dni', 'zkratka_klub']
p[(p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].sort_values(by="pomer_omluvenych_dni")[fields].head(cnt)
Poslanci s nejmenším poměrem dnů, během nichž se omluvali z hlasování PS.
| id_poslanec | jmeno | prijmeni | pomer_omluvenych_dni | pocet_omluvenych_dni | pocet_hlasovacich_dni | zkratka_klub | |
|---|---|---|---|---|---|---|---|
| index | |||||||
| 86 | 1608 | Vladimír | Koníček | 0.051282 | 4 | 78 | KSČM |
| 191 | 1713 | Veronika | Vrecionová | 0.116279 | 15 | 129 | ODS |
| 131 | 1653 | Mikuláš | Peksa | 0.172131 | 21 | 122 | Piráti |
| 32 | 1554 | Jiří | Dolejš | 0.235507 | 65 | 276 | KSČM |
| 107 | 1629 | Tomáš | Martínek | 0.239130 | 66 | 276 | Piráti |
| 41 | 1563 | Milan | Feranec | 0.253623 | 70 | 276 | ANO |
| 157 | 1679 | Jan | Schiller | 0.254032 | 63 | 248 | ANO |
| 18 | 1540 | Stanislav | Berkovec | 0.257246 | 71 | 276 | ANO |
| 97 | 1619 | Roman | Kubíček | 0.257246 | 71 | 276 | ANO |
| 7 | 1528 | Lukáš | Bartoň | 0.257246 | 71 | 276 | Piráti |
cnt = 10
print(f"Poslanci s největším poměrem dnů, během nichž se omluvali z hlasování PS.")
fields = ['id_poslanec', 'jmeno', 'prijmeni', 'pomer_omluvenych_dni', 'pocet_omluvenych_dni', 'pocet_hlasovacich_dni', 'zkratka_klub']
p[(p.pocet_hlasovacich_dni >= minimalni_pocet_hlasovacich_dni)].sort_values(by="pomer_omluvenych_dni")[::-1][fields].head(cnt)
Poslanci s největším poměrem dnů, během nichž se omluvali z hlasování PS.
| id_poslanec | jmeno | prijmeni | pomer_omluvenych_dni | pocet_omluvenych_dni | pocet_hlasovacich_dni | zkratka_klub | |
|---|---|---|---|---|---|---|---|
| index | |||||||
| 213 | 1735 | Jaroslav | Vymazal | 0.907407 | 49 | 54 | ODS |
| 212 | 1734 | Irena | Blažková | 0.890625 | 57 | 64 | ANO |
| 3 | 1524 | Andrej | Babiš | 0.807971 | 223 | 276 | ANO |
| 161 | 1683 | Antonín | Staněk | 0.735507 | 203 | 276 | ČSSD |
| 12 | 1533 | Jiří | Běhounek | 0.721014 | 199 | 276 | ČSSD |
| 158 | 1680 | Karel | Schwarzenberg | 0.721014 | 199 | 276 | TOP09 |
| 164 | 1686 | Martin | Stropnický | 0.714286 | 45 | 63 | ANO |
| 101 | 1623 | Jana | Levová | 0.710145 | 196 | 276 | SPD |
| 207 | 1729 | Václav | Votava | 0.670588 | 114 | 170 | ČSSD |
| 81 | 1603 | Jiří | Kobza | 0.626812 | 173 | 276 | SPD |
Následující analýza slouží k tomu, abychom lépe pochopili, jakým způsobem se hlasujev PS ČR. Proč je tomu třeba rozumět? Některá hlasování (například hlasování o zpochybnění hlasování) mají technický charakter. V některých analýzách je může být vhodné vynechat.
Přibližná pravidla pro určení platnosti hlasování:
hl_pocet = h.id_hlasovani.nunique()
zpochybneni = zph[zph.je_platne == True]
zm_hl = h[h.id_hlasovani.isin(zmh.id_hlasovani)]
zm_hl_pocet = zm_hl.id_hlasovani.nunique()
zp_hl = h[h.id_hlasovani.isin(zpochybneni.id_hlasovani)]
zp_hl_pocet = zp_hl.id_hlasovani.nunique()
pouze_v_tabulce_zpochybneni_pocet = len(set(zph.id_hlasovani) - set(h.id_hlasovani))
pouze_v_tabulce_zmatecne_pocet = len(set(zmh.id_hlasovani) - set(h.id_hlasovani))
print(f"Základní vlastnosti tabulky Hlasovani (pro sněmovnu {h.volebni_obdobi}):")
print(f"- {hl_pocet} hlasování, z toho")
print(f"- {zm_hl_pocet} ({100 * (zm_hl_pocet / hl_pocet):.2f}%) hlasování bylo označeno za zmatečné,")
print(f"- {zp_hl_pocet} ({100 * (zp_hl_pocet / hl_pocet):.2f}%) hlasování bylo zpochybněno.")
df = zpochybneni[zpochybneni.mode__KAT == 'pouze pro stenozáznam']
v1 = h[h.id_hlasovani.isin(df.id_hlasovani)].id_hlasovani.nunique()
print(f"\t- {v1} hlasování z tabulky Hlasování bylo zpochybněno, ale zpochybnění bylo uvedeno jen pro stenozáznam.")
df = zpochybneni[zpochybneni.mode__KAT == 'žádost o opakování']
v1 = h[h.id_hlasovani.isin(df.id_hlasovani)].id_hlasovani.nunique()
print(f"\t- {v1} hlasování z tabulky Hlasování bylo zpochybněno s žádostí o opakování hlasování.")
df = zpochybneni[(zpochybneni.mode__KAT == 'žádost o opakování') & ~(zpochybneni.id_h2.isna()| zpochybneni.id_h3.isna())]
v1 = h[h.id_hlasovani.isin(df.id_hlasovani)].id_hlasovani.nunique()
print(f"\t\t- {v1} hlasování z tabulky Hlasování bylo zpochybněno s žádostí o opakování hlasování, o zpochybnění se hlasovalo a původní hlasování se následně opakovalo.")
df = zpochybneni[(zpochybneni.mode__KAT == 'žádost o opakování') & ~zpochybneni.id_h2.isna() & zpochybneni.id_h3.isna()]
v1 = h[h.id_hlasovani.isin(df.id_hlasovani)].id_hlasovani.nunique()
print(f"\t\t- {v1} hlasování z tabulky Hlasování bylo zpochybněno s žádostí o opakování hlasování, o zpochybnění se hlasovalo, ale původní hlasování se neopakovalo.")
print()
print(f"Dalších {pouze_v_tabulce_zpochybneni_pocet} hlasování je uvedeno pouze v tabulce ZpochybneniHlasovani. ")
print(f"Dalších {pouze_v_tabulce_zmatecne_pocet} hlasování je uvedeno pouze v tabulce ZmatecneHlasovani.")
print()
print(f"Celkově tedy proběhlo ve sněmovně až {hl_pocet + pouze_v_tabulce_zpochybneni_pocet + pouze_v_tabulce_zmatecne_pocet} hlasování.")
print()
print("Poznámka: Tabulka ZmatecneHlasovani nemá explicitně určenou vazbu na danou sněmovnu. Její propojení s tabulkou Hlasování bylo provedeno následující heuristikou: "
"Pro danou sněmovnu se určí minimální a maximální identifikátor hlasování. Pro dané zmatečné hlasování pak musí platit, že min(id(hlasování)) <= id(zmatečného hlasování) <= max(id(hlasování)).")
Základní vlastnosti tabulky Hlasovani (pro sněmovnu 2017): - 8821 hlasování, z toho - 113 (1.28%) hlasování bylo označeno za zmatečné, - 216 (2.45%) hlasování bylo zpochybněno. - 137 hlasování z tabulky Hlasování bylo zpochybněno, ale zpochybnění bylo uvedeno jen pro stenozáznam. - 79 hlasování z tabulky Hlasování bylo zpochybněno s žádostí o opakování hlasování. - 78 hlasování z tabulky Hlasování bylo zpochybněno s žádostí o opakování hlasování, o zpochybnění se hlasovalo a původní hlasování se následně opakovalo. - 1 hlasování z tabulky Hlasování bylo zpochybněno s žádostí o opakování hlasování, o zpochybnění se hlasovalo, ale původní hlasování se neopakovalo. Dalších 512 hlasování je uvedeno pouze v tabulce ZpochybneniHlasovani. Dalších 684 hlasování je uvedeno pouze v tabulce ZmatecneHlasovani. Celkově tedy proběhlo ve sněmovně až 10017 hlasování. Poznámka: Tabulka ZmatecneHlasovani nemá explicitně určenou vazbu na danou sněmovnu. Její propojení s tabulkou Hlasování bylo provedeno následující heuristikou: Pro danou sněmovnu se určí minimální a maximální identifikátor hlasování. Pro dané zmatečné hlasování pak musí platit, že min(id(hlasování)) <= id(zmatečného hlasování) <= max(id(hlasování)).
def flatten(ary):
return [x for l in ary for x in l]
def fce_mezi_hlasovanim_a_hlasovanim_o_zpochybneni_hlasovani_ids(row):
if pd.isna(row['id_h2']):
return []
else:
return list(range(row['id_hlasovani']+1, row['id_h2']))
# Hlasování o zpochybnění hlasování je možné také zkazit nebo zpochybnit.
# Mezi prvním hlasováním o zpochybnění a opakovaným hlasováním může proběhnout několik dalších zpochybněných nebo neplatných hlasování.
def fce_mezi_hlasovanim_o_zpochybneni_a_opakovanym_hlasovanim_ids(row):
if pd.isna(row['id_h2']):
return []
elif pd.isna(row['id_h3']):
return []
else:
return list(range(row['id_h2']+1, row['id_h3']))
mezi_hlasovanim_a_hlasovanim_o_zpochybneni_hlasovani_ids = \
flatten(zpochybneni[zpochybneni.mode__KAT == 'žádost o opakování'].apply(fce_mezi_hlasovanim_a_hlasovanim_o_zpochybneni_hlasovani_ids, axis=1))
mezi_hlasovanim_o_zpochybneni_a_opakovanym_hlasovani_ids = \
flatten(zpochybneni[zpochybneni.mode__KAT == 'žádost o opakování'].apply(fce_mezi_hlasovanim_o_zpochybneni_a_opakovanym_hlasovanim_ids, axis=1))
hlasovani_o_zpochybneni_ids = h[h.id_hlasovani.isin(zpochybneni.id_h2.unique())]
hlasovani_bez_zmatecnych_a_zpochybnenych = h[~h.id_hlasovani.isin(zmh.id_hlasovani)
& ~h.id_hlasovani.isin(zph[zph.mode__KAT == 'žádost o opakování'].id_hlasovani)
& ~h.id_hlasovani.isin(mezi_hlasovanim_o_zpochybneni_a_opakovanym_hlasovani_ids)
& ~h.id_hlasovani.isin(hlasovani_o_zpochybneni_ids)
]
h_platne = hlasovani_bez_zmatecnych_a_zpochybnenych.copy()
h_platne["mira_jednomyslnosti"] = (h_platne.pro - h_platne.proti).abs() / (h_platne.pro + h_platne.proti)
h_platne["mira_jednomyslnosti"].describe()
fig = go.Figure(go.Histogram(
x=h_platne.mira_jednomyslnosti,
hovertemplate="míra jednomyslnosti: %{x}<br>počet hlasování: %{y}<extra></extra>"))
fig.update_layout(width=700, height=400, xaxis=dict(title="míra jednomyslnosti"), yaxis=dict(title="počet hlasování"))
fig.show()
# denní míra jednomyslnosti
precision = 3
def A_razeno_dle_B(x, A, B):
df = x.groupby(A)[B].mean().sort_values(ascending=True)
return("<br>".join(map(str, df.index.astype(str) + ': ' + df.values.round(precision).astype(str))))
days = 7
interval = f"{days}D"
df = pd.DataFrame()
df['mira_jednomyslnosti_za_den_mean'] = h_platne.groupby(h_platne.datum.dt.date).mira_jednomyslnosti.mean()
df['nazev_dlouhy_za_den'] = h_platne.groupby(h_platne.datum.dt.date)[['nazev_dlouhy', 'mira_jednomyslnosti']].apply(
lambda x: A_razeno_dle_B(x, "nazev_dlouhy", "mira_jednomyslnosti")
)
df.index = pd.to_datetime(df.index)
fig = go.Figure()
fig.add_trace(go.Scatter(
x=df.index,
y=df.mira_jednomyslnosti_za_den_mean,
text=df.nazev_dlouhy_za_den,
name="míra jednomyslnosti za den",
mode="markers",
marker=dict(
size=5,
color=df.mira_jednomyslnosti_za_den_mean,
colorscale='RdYlGn', # one of plotly colorscales
showscale=True
),
hovertemplate =
'<b>%{x}</b>'+
'<br><br><b>Průměrná míra jednomyslnosti</b>: <i>%{y:.3f}</i>'+
'<br><br><b>Hlasování dle míry jednomyslnosti (vzestupně):</b><br>%{text}<extra></extra>',
hoverlabel=dict(
bgcolor='white',
font=dict(color='black')
)
))
fig.update_layout(title="Denní míra jednomyslnosti", xaxis=dict(title="datum [jednotlivé dny]"), yaxis=dict(title="míra jednomyslnosti"))
fig.show()
print(f"Jednomyslně schválená hlasování (vysoká míra jednomyslnosti): {h_platne[h_platne.mira_jednomyslnosti == 1].index.size}")
jednomyslna_temata = h_platne[h_platne.mira_jednomyslnosti == 1].groupby('nazev_dlouhy').size().sort_values(ascending=False)
print(jednomyslna_temata.head(20))
Jednomyslně schválená hlasování (vysoká míra jednomyslnosti): 3065
nazev_dlouhy
Pořad schůze 531
128
Návrh na vyslovení souhlasu PS s prodloužením doby nouzového stavu 83
Návrh na změny ve složení orgánů Poslanecké sněmovny 61
Návrhy PS na propůjčení nebo udělení státních vyznamenání 44
Vl.n.z. v souv.s elektronizací postupů orgánů veřejné moci 33
Novela z. - školský zákon 26
Návrhy Poslanecké sněmovny na propůjčení nebo udělení státních vyzname 24
Novela z. o kompenzačním bonusu 23
Novela z. - trestní řád 23
Novela z. o daních z příjmů 23
Novela z. o státním rozpočtu ČR na rok 2020 22
Vl. n. z. kterým se mění některé zákony v oblasti daní - EU 20
Usn.PS.1162 18
Vl.n.z. o evidenci skutečných majitelů - EU 18
Novela z. - trestní zákoník - EU 17
Novela ústav. z. - Ústava ČR 16
Náv. na ustavení výborů PS 16
Novela z. o pomoci v hmotné nouzi 16
Novela z. o urychlení výstavby dopravní infrastruktury 16
dtype: int64
print(f"Hlasování s nízkou mírou jednomyslnosti (zcela vyrovnané pro a proti)): {h_platne[h_platne.mira_jednomyslnosti == 0].index.size}")
nejednomyslna_temata = h_platne[h_platne.mira_jednomyslnosti == 0].groupby('nazev_dlouhy').size().sort_values(ascending=False)
print(nejednomyslna_temata.head(20))
Hlasování s nízkou mírou jednomyslnosti (zcela vyrovnané pro a proti)): 72 nazev_dlouhy Novela z. o evidenci tržeb - EU 28 Pořad schůze 7 Vl.n.z. o kompenzačním bonusu v souv. s krizovými opatřeními 5 Vl.n.z. o státním rozpočtu ČR na rok 2021 2 Vl.n.z.o opatř.ke zmírnění dopadů SARS CoV-2 na nájemce byt. 2 Návrh na vyslovení nedůvěry vládě České republiky 2 Novela z. o rozpočtových pravidlech 2 Novela z. - horní zákon 2 Novela z. o evidenci tržeb 1 Novela z. o státním občanství ČR 1 Novela z. o důchodovém pojištění 1 Novela z. o některých úpravách v oblasti evidence tržeb 1 Novela z. o pomoci v hmotné nouzi 1 Novela z. o bankách - EU 1 Novela z. o potravinách a tabákových výrobcích - EU 1 N.z., kterým se mění zák. opatření Senátu č. 340/2013 Sb. 1 Vln. z. o kompenzačním bonusu pro rok 2021 1 Novela z. o ČNB 1 Novela z. o vnitrozemské plavbě - EU 1 Novela z. o vodách (vodní zákon) - EU 1 dtype: int64
# Témata hlasování s nejvyšší mírou jednomyslnosti a jejich počty
cnt = 5
x = pd.DataFrame()
x['celkovy_pocet_hlasovani_dle_tematu'] = h_platne.groupby('nazev_dlouhy').size()
x['prumerna_mira_jednomyslnosti_dle_tematu'] = h_platne.groupby('nazev_dlouhy')['mira_jednomyslnosti'].mean()
x.sort_values(by='prumerna_mira_jednomyslnosti_dle_tematu', ascending=False).head(cnt)
| celkovy_pocet_hlasovani_dle_tematu | prumerna_mira_jednomyslnosti_dle_tematu | |
|---|---|---|
| nazev_dlouhy | ||
| Návrh na volbu členů nebo ustavení SK KPO | 1 | 1.0 |
| Změny přílohy III Rotterdamské úmluvy | 2 | 1.0 |
| Návrh Pravidel hospodaření poslaneckých klubů pro rok 2018 | 1 | 1.0 |
| Změny příloh Úml.o ochr.stěh.druhů volně žij.živočichů | 2 | 1.0 |
| Změny příloh A a C Stockholmské úmluvy | 3 | 1.0 |
# Témata hlasování s nízkou mírou jednomyslnosti a jejich počty
cnt = 5
x = pd.DataFrame()
x['celkovy_pocet_hlasovani_dle_tematu'] = h_platne.groupby('nazev_dlouhy').size()
x['prumerna_mira_jednomyslnosti_dle_tematu'] = h_platne.groupby('nazev_dlouhy')['mira_jednomyslnosti'].mean()
x.sort_values(by='prumerna_mira_jednomyslnosti_dle_tematu', ascending=False).tail(cnt)
| celkovy_pocet_hlasovani_dle_tematu | prumerna_mira_jednomyslnosti_dle_tematu | |
|---|---|---|
| nazev_dlouhy | ||
| Písemná interpelace V. Munzara na A. Schillerovou | 1 | 0.083333 |
| Novela z. o evidenci tržeb - EU | 857 | 0.060626 |
| Písemná interpelace V. Munzara na A. Schillerovou ve věci poruš. ústav | 1 | 0.054054 |
| Písemná interpelace V. Munzara na A. Schillerovou ve věci odměňování ú | 1 | 0.038961 |
| Návrh na vyslovení nedůvěry vládě České republiky | 3 | 0.022556 |
%%time
df = hp[hp.id_hlasovani.isin(h_platne.id_hlasovani)]
data = df[['id_osoba', 'id_hlasovani', 'vysledek', 'zkratka_klub']]\
.set_index('id_osoba')\
.sort_values(by=['zkratka_klub'])[['id_hlasovani', 'vysledek']]\
.groupby('id_osoba', sort=False)\
.apply(lambda g: list(map(tuple, g.values))).to_dict()
data = {osoba: [str(hl_idx) + '_' + vysledek for hl_idx, vysledek in data[osoba]] for osoba in data.keys()}
CPU times: user 5.5 s, sys: 316 ms, total: 5.81 s Wall time: 5.81 s
%%time
def jaccard_similarity(list1, list2):
intersection = len(list(set(list1).intersection(list2)))
union = (len(list1) + len(list2)) - intersection
return float(intersection) / union
m = {}
for osoba1, v1 in data.items():
if osoba1 not in m:
m[osoba1] = {}
for osoba2, v2 in data.items():
m[osoba1][osoba2] = jaccard_similarity(v1, v2)
CPU times: user 49.4 s, sys: 5.59 ms, total: 49.4 s Wall time: 49.4 s
korelace_df = pd.DataFrame(m)
osoby = {id_osoba: hp[hp.id_osoba == id_osoba][['jmeno', 'prijmeni', 'zkratka_kandidatka','nazev_kraj_cz', 'zkratka_klub']].iloc[0] for id_osoba in korelace_df}
jmeno_prijmeni = [f"{osoby[id_osoba]['jmeno']} {osoby[id_osoba]['prijmeni']}" for id_osoba in korelace_df.index]
zkratka_klub = [osoby[id_osoba]['zkratka_klub'] for id_osoba in korelace_df.index]
label = [f"{j} ({zk})" for j, zk in zip(jmeno_prijmeni, zkratka_klub)]
import plotly.graph_objects as go
fig = go.Figure(data=go.Heatmap(
z=korelace_df,
x=label,
y=label,
colorscale='Viridis',
hovertemplate="%{x}<br>%{y}<br>Podobnost hlasování: %{z}<extra></extra>"
))
fig.update_layout(title='Podobnost hlasování poslanců', width=800, height=800)
fig.update_xaxes(type='category', tickangle=45)
fig.update_yaxes(type='category', autorange='reversed')
fig.show()
print(f"Poslední běh notebooku: {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}.")
Poslední běh notebooku: 07.04.2021 03:25:51.